// ========== Copyright Header Begin ==========================================
// 
// OpenSPARC T1 Processor File: Ni_UnimplAsiHandler.cc
// Copyright (c) 2006 Sun Microsystems, Inc.  All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
// 
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
// 
// The above named program is distributed in the hope that it will be 
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
// 
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
// 
// ========== Copyright Header End ============================================
/************************************************************************
**  
**  Copyright (C) 2002, Sun Microsystems, Inc.
**
**  Sun considers its source code as an unpublished, proprietary
**  trade secret and it is available only under strict license provisions.
**  This copyright notice is placed here only to protect Sun in the event 
**  the source is deemed a published work. Disassembly, decompilation,
**  or other means of reducing the object code to human readable form
**  is prohibited by the license agreement under which this code is
**  provided to the user or company in possession of this copy."
**
*************************************************************************/
#include "Ni/Ni_UnimplAsiHandler.h"
#include "Ni/Ni_Trap.h"
#include "StdMacros.h"
#include <sstream>

using namespace std;
using namespace Riesling;

Ni_UnimplAsiHandler::Ni_UnimplAsiHandler()
{}

Ni_UnimplAsiHandler::Ni_UnimplAsiHandler( const Ni_UnimplAsiHandler & orig )
{
	junk_ = orig.junk_;
}

Ni_UnimplAsiHandler::~Ni_UnimplAsiHandler()
{
}

const Ni_UnimplAsiHandler &
Ni_UnimplAsiHandler::operator=( const Ni_UnimplAsiHandler & rhs )
{
    junk_ = rhs.junk_;

    return *this;
}

bool
Ni_UnimplAsiHandler::operator==( const Ni_UnimplAsiHandler & rhs ) const
{ 
    return junk_ == rhs.junk_;
}

string
Ni_UnimplAsiHandler::toString() const
{
    ostringstream os;
    return os.str();
}

void 
Ni_UnimplAsiHandler::setAsiDispatcher( AsiDispatcher &dispatcher )
{}


#define NI_GENKEY(asi, va) ( (((Uint64T)asi & 0xff)<<48) ^ (Uint64T)va )

void 
Ni_UnimplAsiHandler::asiWriteHandler( AsiDispatchPacket &p )
{
	static	map<Uint64T, Uint64T> jj;

    switch( p.getAccessIndex() ){
	case EXCEPTION:
	    {
		ostringstream err;
		err << "The write to asi 0x" << hex << (int)p.getAsi() << " at addr 0x";
		err << RIESLING_VADDR_FORMAT << p.getVaddr() << " is not implemented.";
		RIESLING_THROW_DOMAIN_ERROR( err.str() );
	    } 
	    break;
	case CONSUME:
	    p.setResponse( AsiDispatchPacket::OK );
	    break;

	case NOP:
	    RIESLING_TRAP(Ni_Trap::treatAsNoop);
	    break;

	case REGISTER:
	    {
    	        Uint64T k;

	        k = NI_GENKEY(p.getAsi(), p.getVaddr());

	   	junk_[k] = p.getData();

	        p.setResponse( AsiDispatchPacket::OK );
	    }
	    break;

	case REGISTER_28B:
	    {
    	        Uint64T k;

	        k = NI_GENKEY(p.getAsi(), p.getVaddr());

	   	junk_[k] = p.getData() & 0xfffffffULL;	// take only low 28 bits

	        p.setResponse( AsiDispatchPacket::OK );
	    }
	    break;

	case REGISTERV:
	    {
  	  	Uint64T k;

	        k = NI_GENKEY(p.getAsi(), p.getVaddr());

	        cout << "Ni DUMMY ASI, WR 0x" << hex << (int)p.getAsi();
	        cout << " VA 0x" << RIESLING_VADDR_FORMAT << p.getVaddr();
	        cout << " Val 0x" << hex <<  p.getData() << endl;
	    

	        junk_[k] = p.getData();
	        p.setResponse( AsiDispatchPacket::OK );
	    }
	    break;

	default:
	    p.setResponse( AsiDispatchPacket::HANDLER_ERROR );
	    break;
    }
}


void 
Ni_UnimplAsiHandler::asiReadHandler( AsiDispatchPacket &p )
{
    switch( p.getAccessIndex() ){
	case EXCEPTION:
	    {
		ostringstream err;
		err << "The read to asi 0x" << hex << (int)p.getAsi() << " at addr 0x";
		err << RIESLING_VADDR_FORMAT << p.getVaddr() << " is not implemented.";
		RIESLING_THROW_DOMAIN_ERROR( err.str() );
	    } 
	    break;

	case CONSUME:
	    p.setData( 0 );
	    p.setResponse( AsiDispatchPacket::OK );
	    break;

	case NOP:
	    RIESLING_TRAP(Ni_Trap::treatAsNoop);
	    break;

	case REGISTER_28B:
	case REGISTER:
	    {
		Uint64T	k;

		k = NI_GENKEY(p.getAsi(), p.getVaddr());
	    	p.setData( junk_[k] );
	    	p.setResponse( AsiDispatchPacket::OK );
	    }
	    break;

	case REGISTERV:
  	    {
		Uint64T	k;

		k =  NI_GENKEY(p.getAsi(), p.getVaddr());

	    	cout << "Ni DUMMY ASI, RD 0x" << hex << (int)p.getAsi();
	    	cout << " VA 0x" << RIESLING_VADDR_FORMAT << p.getVaddr();
	    	cout << " Val 0x" << hex << junk_[k] << endl;

	    	p.setData( junk_[k] );
	    	p.setResponse( AsiDispatchPacket::OK );
	    }
	    break;

	default:
	    p.setResponse( AsiDispatchPacket::HANDLER_ERROR );
	    break;
    }
}


